/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2016年4月28日
 * V4.0
 */
package com.jphenix.servlet.multipart.instancea;

import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.File;
import java.io.FileInputStream;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;

import com.jphenix.share.util.SFilesUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.servlet.api.IResponse;

/**
 * 图像输出类
 * 
 * 2019-08-19 增加了更加实用的方法
 * 2019-09-05 修改了只支持jpg的错误，显示png时强制按照jpg显示的错误
 * 2022-09-04 隔离了ServletApi，兼容新老Tomcat
 * 
 * @author MBG
 * 2016年4月28日
 */
@ClassInfo({"2022-09-04 21:58","图像输出类"})
public class ImgShow {

	protected String    basePath = null; // 保存根路径
	protected IResponse response = null; // 页面反馈
	
	/**
	 * 构造函数
	 * 2007-11-24下午03:16:19
	 */
	public ImgShow(IResponse resp,String basePath) {
		super();
		this.response = resp;
		this.basePath = basePath;
	}
	
	
	/**
	 * 构造函数
	 * 2019-08-19 11:02
	 */
	public ImgShow(IResponse resp) {
		super();
		this.response = resp;
		this.basePath = null;
	}
	
	
	/** 显示图片
	 * @param response   页面反馈
	 * @param path       图片文件绝对路径
	 * @param qality     压缩比 1不压缩   0.1 最小值
	 * @param minLength  文件小于多大，不启用压缩  为0时，启用压缩
	 * 2019年8月19日
	 * @author MBG
	 */
	public static void show(IResponse response,String path,float qality) {
		show(response,path,qality,0);
	}
	
	/**
	 * 显示图片
	 * @param response   页面反馈
	 * @param path       图片文件绝对路径
	 * @param qality     压缩比 1不压缩   0.1 最小值
	 * @param minLength  文件小于多大，不启用压缩  为0时，启用压缩
	 * 2019年8月19日
	 * @author MBG
	 */
	public static void show(IResponse response,String path,float qality,long minLength) {
		//文件对象
		File imgFile = new File(path);
		if(!imgFile.exists()) {
			System.err.print("[err] Error:ImgShow.show The File:["+path+"] Not Exists");
			return;
		}
		if(minLength<1 || imgFile.length()>minLength){
			//默认设置压缩大小
			if(qality<0 || qality>1){
			  qality = 0.3f;
			}
		}else {
			qality = 1f;
		}
		BufferedImage src = null;  
		ImageWriter imgWrier;  
		ImageWriteParam imgWriteParams;  
		FileInputStream is = null; //文件读入流

		//获取文件扩展名
		String extName = SFilesUtil.getFileExtName(path).toLowerCase();
		
		//指定写图片的方式为 jpg  
		imgWrier = ImageIO.getImageWritersByFormatName(extName).next();  
		imgWriteParams = new JPEGImageWriteParam(null);  
		// 要使用压缩，必须指定压缩方式为MODE_EXPLICIT  
		imgWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);  
		// 这里指定压缩的程度，参数qality是取值0~1范围内，  
		imgWriteParams.setCompressionQuality(qality);  
		imgWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED);  
		ColorModel colorModel = ColorModel.getRGBdefault();

		// 指定压缩时使用的色彩模式  
		imgWriteParams
		  	.setDestinationType(
		  		new javax.imageio.ImageTypeSpecifier(colorModel,colorModel.createCompatibleSampleModel(16, 16)));  

		try {  
		  	is = new FileInputStream(imgFile);
			src = ImageIO.read(is);  
			imgWrier.reset();  
			
		  	System.setProperty("java.awt.headless","true");
			response.flushBuffer();
		  	response.setContentType("image/jpeg");
			response.setHeader("Cache-Control", "no-cache");
			response.setHeader("Pragma", "no-cache");
			response.setDateHeader("Expires", 0); 
		  
			imgWrier.setOutput(ImageIO.createImageOutputStream(response.iGetOutputStream()));
		  
			// 调用write方法，就可以向输入流写图片  
			imgWrier.write(null, new IIOImage(src, null, null), imgWriteParams);  
		} catch(Exception e){  
			e.printStackTrace();  
		} finally{
		  try{
		    is.close();
		  }catch(Exception e){}
		  is = null;
		}
	}
	
	
	/**
	 * 输出图片
	 * @param response 页面反馈对象
	 * @param image 图片对象
	 * @param qality 压缩比  0~1之间的浮点数
	 * 2016年9月28日
	 * @author MBG
	 */
	public static void show(IResponse response,BufferedImage image,float qality) {
		//默认设置压缩大小
		if(qality<0 || qality>1){
		  qality = 0.3f;
		}
		//指定写图片的方式为 jpg  
		ImageWriter imgWrier = ImageIO.getImageWritersByFormatName("jpg").next();  
		ImageWriteParam imgWriteParams = new JPEGImageWriteParam(null);  
		// 要使用压缩，必须指定压缩方式为MODE_EXPLICIT  
		imgWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);  
		// 这里指定压缩的程度，参数qality是取值0~1范围内，  
		imgWriteParams.setCompressionQuality(qality);  
		imgWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED);  
		try {  
			imgWrier.reset();  
		  	System.setProperty("java.awt.headless","true");
			response.flushBuffer();
		  	response.setContentType("image/jpeg");
			response.setHeader("Cache-Control", "no-cache");
			response.setHeader("Pragma", "no-cache");
			response.setDateHeader("Expires", 0); 
			imgWrier.setOutput(ImageIO.createImageOutputStream(response.iGetOutputStream()));
			// 调用write方法，就可以向输入流写图片  
			imgWrier.write(null, new IIOImage(image, null, null), imgWriteParams);  
		} catch(Exception e){  
			e.printStackTrace();  
		} finally {
			try {
				imgWrier.dispose();
			}catch(Exception e) {}
			imgWrier = null;
			image = null;
		}
	}
	
	
	/**
	 * 显示压缩后的图片
	 * @param path 图片相对路径（相对于 WEB-INF/classes）
	 * @param qality 压缩比  0~1之间的浮点数
	 * @throws Exception 异常
	 * 2016年4月28日
	 * @author MBG
	 */
	public void show(String path,float qality) throws Exception {
		//默认设置压缩大小
		if(qality<0 || qality>1){
		  qality = 0.3f;
		}
		BufferedImage src = null;  
		ImageWriter imgWrier;  
		ImageWriteParam imgWriteParams;  
		FileInputStream is = null; //文件读入流

		//指定写图片的方式为 jpg  
		imgWrier = ImageIO.getImageWritersByFormatName("jpg").next();  
		imgWriteParams = new JPEGImageWriteParam(null);  
		// 要使用压缩，必须指定压缩方式为MODE_EXPLICIT  
		imgWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);  
		// 这里指定压缩的程度，参数qality是取值0~1范围内，  
		imgWriteParams.setCompressionQuality(qality);  
		imgWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED);  
		ColorModel colorModel = ColorModel.getRGBdefault();

		// 指定压缩时使用的色彩模式  
		imgWriteParams
		  	.setDestinationType(
		  		new javax.imageio.ImageTypeSpecifier(colorModel,colorModel.createCompatibleSampleModel(16, 16)));  

		try {  
		  	is = new FileInputStream(new File(SFilesUtil.getAllFilePath(path,basePath)));
			src = ImageIO.read(is);  
			imgWrier.reset();  
			
		  	System.setProperty("java.awt.headless","true");
			response.flushBuffer();
		  	response.setContentType("image/jpeg");
			response.setHeader("Cache-Control", "no-cache");
			response.setHeader("Pragma", "no-cache");
			response.setDateHeader("Expires", 0); 
		  
			imgWrier.setOutput(ImageIO.createImageOutputStream(response.iGetOutputStream()));
		  
			// 调用write方法，就可以向输入流写图片  
			imgWrier.write(null, new IIOImage(src, null, null), imgWriteParams);  
		} catch(Exception e){  
			e.printStackTrace();  
		} finally{
		  try{
		    is.close();
		  }catch(Exception e){}
		  is = null;
		}
	}
}
